﻿using AlgoritmoConstrutivo.entidades;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AlgoritmoConstrutivo.leitor
{
    public class InstanceReader
    {
        private BunchFileReader bf_r;
        private PonderadaFileReader pf_r;
        private XMLInstanceReader xml_r;

        private List<instance> pequenas = new List<instance>();
        private List<instance> medias = new List<instance>();
        private List<instance> grandes = new List<instance>();




        public Grafo ReadFile(FileInfo arquivo)
        {

            Grafo gr = new Grafo();



            //formatação de XML (somente as do experimento 1 possuem este formato)
            if (CheckTypeOfInstance(arquivo) == "XML")
            {
                xml_r = new XMLInstanceReader();
                gr =  xml_r.ExtractInstance(arquivo);
                gr.EhPonderada = false;
            }

            //formatação de ponderadas (somente as ponderadas possuem este formato)
            else if (CheckTypeOfInstance(arquivo) == "Ponderada")
            {
                pf_r = new PonderadaFileReader();
                gr =  pf_r.ExtractInstance(arquivo);
                gr.EhPonderada = true;

            }

            //formatação normal sem ser XML
            else if (CheckTypeOfInstance(arquivo) == "Normal")
            {
                bf_r = new BunchFileReader();
                gr = bf_r.ExtractInstance(arquivo);
                gr.EhPonderada = false;

            }


            instance instancia = new instance();

            instancia.Nome = gr.Nome;
            instancia.Modulos = gr.RetornarNumNos();
            instancia.Dependencias = gr.NumeroDependencias();
            instancia.Peso = gr.EhPonderada;

            if (instancia.Modulos < 100)
                pequenas.Add(instancia);

            else if (instancia.Modulos >= 100 && instancia.Modulos < 200)
                medias.Add(instancia);

            else
                grandes.Add(instancia);

            return gr;

        }

        private string CheckTypeOfInstance(FileInfo arquivo)
        {
            if (arquivo.FullName.Contains(".xml") || arquivo.FullName.Contains(".XML"))
                return "XML";
           

            String [] linhaArquivo = File.ReadAllLines(arquivo.FullName);

            String[] linhaFormatada = linhaArquivo[0].Split('\n');

            String[] tokenizar = null;

            if (linhaFormatada[0].Contains('\t'))
                tokenizar = linhaFormatada[0].Split('\t');
            else
                 tokenizar = linhaFormatada[0].Split(' ');


            int ultimoIndice = tokenizar.Length;
            ultimoIndice--;
            int result = 0;

            if (Int32.TryParse(tokenizar[ultimoIndice], out result))
                return "Ponderada";

            else 
                return "Normal";

        }

        internal void GenerateTableWithInstances(DirectoryInfo dir, DirectoryInfo DirInst)
        {
            FileInfo pequenas = new FileInfo(dir.FullName + "\\pequenas.txt");
            FileInfo medias = new FileInfo(dir.FullName + "\\medias.txt");
            FileInfo grandes = new FileInfo(dir.FullName + "\\grandes.txt");

            if (!Directory.Exists(DirInst.FullName + "\\Pequenas"))
                Directory.CreateDirectory(DirInst.FullName + "\\Pequenas");

            if (!Directory.Exists(DirInst.FullName + "\\Medias"))
                Directory.CreateDirectory(DirInst.FullName + "\\Medias");

            if (!Directory.Exists(DirInst.FullName + "\\Grandes"))
                Directory.CreateDirectory(DirInst.FullName + "\\Grandes");
            


            String resul = null;
            List<instance> pequenasList = this.pequenas.OrderBy(o => o.Modulos).ToList();
            foreach (instance inst in pequenasList)
            {
                if (!File.Exists(DirInst.FullName + "\\Pequenas\\" + inst.Nome))
                    File.Copy(DirInst.FullName + "\\" + inst.Nome, DirInst.FullName + "\\Pequenas\\" + inst.Nome,true);
                resul += inst;
             
            }
            File.WriteAllText(pequenas.FullName, resul);


            resul = null;
            List<instance> mediasList = this.medias.OrderBy(o => o.Modulos).ToList();
            foreach (instance inst in mediasList)
            {
                if (!File.Exists(DirInst.FullName + "\\Medias\\" + inst.Nome))
                    File.Move(DirInst.FullName + "\\" + inst.Nome, DirInst.FullName + "\\Medias\\" + inst.Nome);
                resul += inst;

            }
            File.WriteAllText(medias.FullName, resul);


            resul = null;
            List<instance> grandesList = this.grandes.OrderBy(o => o.Modulos).ToList();
            foreach (instance inst in grandesList)
            {
                if (!File.Exists(DirInst.FullName + "\\Grandes\\" + inst.Nome))
                    File.Move(DirInst.FullName + "\\" + inst.Nome, DirInst.FullName + "\\Grandes\\" + inst.Nome);
                resul += inst;

            }
            File.WriteAllText(grandes.FullName, resul);

        }
    }
}
